</object>
</property>
</object>
+ <object class="GtkFilterListModel" id="searchListModel">
+ <property name="model">sortModel</property>
+ <property name="filter">searchFilter</property>
+ </object>
<template class="ExtensionsWindow" parent="AdwApplicationWindow">
<property name="default-width">800</property>
<property name="default-height">500</property>
</property>
</object>
</child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">search</property>
+ <property name="child">
+ <object class="AdwPreferencesPage">
+ <child>
+ <object class="AdwPreferencesGroup">
+ <child>
+ <object class="GtkListBox" id="searchList">
+ <property name="selection-mode">none</property>
+ <accessibility>
+ <property name="label" translatable="yes">Search Results</property>
+ </accessibility>
+ <style>
+ <class name="boxed-list"/>
+ </style>
+ </object>
+ </child>
+ </object>
+ </child>
+ </object>
+ </property>
+ </object>
+ </child>
+ <child>
+ <object class="GtkStackPage">
+ <property name="name">noresults</property>
+ <property name="child">
+ <object class="AdwStatusPage">
+ <property name="icon-name">org.gnome.Extensions-symbolic</property>
+ <property name="title" translatable="yes">No Results Found</property>
+ <property name="description" translatable="yes">Try a different search.</property>
+ </object>
+ </property>
+ </object>
+ </child>
<child>
<object class="GtkStackPage">
<property name="name">placeholder</property>
'searchFilter',
'userListModel',
'systemListModel',
+ 'searchListModel',
'userGroup',
'userList',
'systemGroup',
'systemList',
+ 'searchList',
'mainStack',
'searchBar',
- 'searchButton',
'searchEntry',
'updatesBanner',
],
this._searchEntry.connect('search-changed',
() => (this._searchFilter.search = this._searchEntry.text));
+ this._searchBar.connect('notify::search-mode-enabled',
+ () => this._syncVisiblePage());
+ this._searchListModel.connect('notify::n-items',
+ () => this._syncVisiblePage());
- this._userList.set_placeholder(new Gtk.Label({
- label: _('No Matches'),
- margin_start: 12,
- margin_end: 12,
- margin_top: 12,
- margin_bottom: 12,
- }));
this._userList.connect('row-activated', (_list, row) => row.activate());
this._userGroup.connect('notify::visible', () => this._syncVisiblePage());
- this._systemList.set_placeholder(new Gtk.Label({
- label: _('No Matches'),
- margin_start: 12,
- margin_end: 12,
- margin_top: 12,
- margin_bottom: 12,
- }));
this._systemList.connect('row-activated', (_list, row) => row.activate());
this._systemGroup.connect('notify::visible', () => this._syncVisiblePage());
this._sortModel.model = extensionManager.extensions;
- this._userList.bind_model(new Gtk.FilterListModel({
- filter: this._searchFilter,
- model: this._userListModel,
- }), extension => new ExtensionRow(extension));
- this._systemList.bind_model(new Gtk.FilterListModel({
- filter: this._searchFilter,
- model: this._systemListModel,
- }), extension => new ExtensionRow(extension));
+ this._userList.bind_model(this._userListModel,
+ extension => new ExtensionRow(extension));
+ this._systemList.bind_model(this._systemListModel,
+ extension => new ExtensionRow(extension));
+ this._searchList.bind_model(this._searchListModel,
+ extension => new ExtensionRow(extension));
extensionManager.connect('extensions-loaded',
() => this._extensionsLoaded());
_syncVisiblePage() {
const {extensionManager} = this.application;
+ const {searchModeEnabled} = this._searchBar;
if (extensionManager.failed)
this._mainStack.visible_child_name = 'noshell';
+ else if (searchModeEnabled && this._searchListModel.get_n_items() > 0)
+ this._mainStack.visible_child_name = 'search';
+ else if (searchModeEnabled)
+ this._mainStack.visible_child_name = 'noresults';
else if (this._userGroup.visible || this._systemGroup.visible)
this._mainStack.visible_child_name = 'main';
else